/**
 * This file is used to create a visualization
 */

/**
 * Get the position of the data at the given index in the list based on the
 * dateList
 *
 * @param datas
 *            the list of data
 * @param index
 *            the index
 * @param dateList
 *            the list of date
 * @param datatime
 * 			  the time used to group data (year, month, etc)
 */
function getXPosition(datas, index, dateList, datatime) {
	for(var d in dateList) {
		if(datatime == "month") {
			var y = parseInt(datas[index].key.split("-")[0], 10)
			var m = parseInt(datas[index].key.split("-")[1], 10)
			if(dateList[d] == (getMonthName(m) + " " + y))
				return d;
		}else if(datatime == "year") {
			var y = parseInt(datas[index].key.split("-")[0], 10)
			if(dateList[d] == y + "")
				return d;
		}else if(datatime == "day") {
			var y = parseInt(datas[index].key.split("-")[0], 10)
			var m = parseInt(datas[index].key.split("-")[1], 10)
			var dy = parseInt(datas[index].key.split("-")[2], 10)
			if(dateList[d] == (dy+" "+getMonthName(m) + " " + y))
				return d;
		}

	}
	return -1;
}

var maximumNumberOfDataToShow = 40;
var stepSizeOnMoveChart = 20;

/**
 * Function called when the data has been clicked
 */
function selectedData(id, date) {
	date += ""
	// POST request to the server
	var http = new XMLHttpRequest();
	var url = "getdata";
	var params = "couchdb=" + couchdb + "&database=" + project + "&type=" + id + "&date=" + date + "&datelen=" + date.length;
	http.open("POST", url, true);

	//Send the proper header information along with the request
	http.setRequestHeader("Content-type", "application/x-www-form-urlencoded");
	http.setRequestHeader("Content-length", params.length);
	http.setRequestHeader("Connection", "close");

	http.onreadystatechange = function() {//Call a function when the state changes.
		if(http.readyState == 4 && http.status == 200) {
			// create the dialog
			if(http.responseText != "No data found") {
				list = JSON.parse(http.responseText);
				var text = "<table>";
				if(id == "emails")
					text += "<tr><th>Date</th><th>Subject</th><th>Author</th></tr>";
				if(id == "commits")
					text += "<tr><th>Date</th><th>Log Message</th><th>Author</th></tr>";
				if(id == "issues")
					text += "<tr><th>Date reported</th><th>Summary</th><th>Reported by</th></tr>";
				for(var i in list) {
					if(id == "emails"){
						var click = "getSingleEmail('"+list[i].id+"')";
						text += "<tr><td>" + list[i].date.toString() + '</td><td> <a href="#" onClick="'+click+'">' + list[i].subject.replace("Subject: ", "") + "</a></td><td>" + list[i].sender.replace("From: ", "") + "</td></tr>";
					}
					if(id == "commits"){
						var click = "getSingleCommit('"+list[i].id+"')";
						text += "<tr><td>" + list[i].date.toString() + '</td><td> <a href="#" onClick="'+click+'">' + list[i].log + "</td><td>" + list[i].author + "</a></td></tr>";
					}
					if(id == "issues"){
						var click = "getSingleIssue('"+list[i]._id+"')";
						text += "<tr><td>" + list[i].dateReported.toString() + '</td><td> <a href="#" onClick="'+click+'">' + list[i].summary + "</td><td>" + list[i].author + "</a></td></tr>";
					}
				}
				text += "</table>"
			} else
				var text = "No data found";

			var $dialog = $('<div class="dialog-popup"></div>').html(text).dialog({
				autoOpen : false,
				title : id,
				height : 500,
				width : 900
			});

			$dialog.dialog('open');
		}
	}
	http.send(params);
}

/**
 * Open a page for single email
 */
function getSingleEmail(id){
	var addr = "getsingle_email?";
	var cou = "couchdb="+couchdb;
	var db = "&database="+project;
	id = id.replace(/&/g, '___')
	var ids = "&id="+id;
	window.open(addr+cou+db+ids, '_blank');
}
/**
 * Open a page for single commit
 */
function getSingleCommit(id){
	var addr = "getsingle_commit?";
	var cou = "couchdb="+couchdb;
	var db = "&database="+project;
	id = id.replace(/&/g, '___')
	var ids = "&id="+id;
	window.open(addr+cou+db+ids, '_blank');
}
/**
 * Open a page for single issue
 */
function getSingleIssue(id){
	var addr = "getsingle_issue?";
	var cou = "couchdb="+couchdb;
	var db = "&database="+project;
	id = id.replace(/&/g, '___')
	var ids = "&id="+id;
	window.open(addr+cou+db+ids, '_blank');
}

/**
 * Distributes the issues so that each month on the label list has
 * a correspondent issue. It there is no issue at that month create a issue with 0
 */
function distributesIssuesForLabels(labels, issueList, datatime) {
	newIssueList = new Array(labels.length)
	for(var i in labels) {
		found = false;
		for(var j in issueList) {
			if(datatime == "month") {
				var y = parseInt(issueList[j].key.split("-")[0], 10)
				var m = parseInt(issueList[j].key.split("-")[1], 10)
				if(labels[i] == (getMonthName(m) + " " + y)) {
					newIssueList[i] = issueList[j]
					found = true;
					break;
				}
			}else if(datatime == "year") {
				var y = parseInt(issueList[j].key, 10)
				if(labels[i] == y) {
					newIssueList[i] = issueList[j]
					found = true;
					break;
				}
			}else if(datatime == "day"){
				var y = parseInt(issueList[j].key.split("-")[0], 10)
				var m = parseInt(issueList[j].key.split("-")[1], 10)
				var d = parseInt(issueList[j].key.split("-")[2], 10)
				if(labels[i] == (d+" "+getMonthName(m) + " " + y)) {
					newIssueList[i] = issueList[j]
					found = true;
					break;
				}
			}

		}
		if(!found) {
			if(datatime == "month") {
				newIssueList[i] = {
					"key" : createYearMonthFromLabel(labels[i]),
					"value" : 0
				}
			}else if(datatime == "year") {
				newIssueList[i] = {
					"key" : labels[i],
					"value" : 0
				}
			}else if(datatime == "day") {
				newIssueList[i] = {
					"key" : createYearMonthDayFromLabel(labels[i]),
					"value" : 0
				}
			}

		}
	}
	return newIssueList;
}

function drawChart() {
	//create commit list
	if(commitList.length != 0) {
		foundcommit = true;
	} else
		foundcommit = false;
	//create email list
	if(emailList.length != 0) {
		foundemail = true;
	} else
		foundemail = false;
	//create issue list
	if(issueList.length != 0) {
		foundissue = true;
	} else
		foundissue = false;

	// get minimum and maximum x values
	if(foundcommit && foundemail) {
		if(emailList[0].key < commitList[0].key)
			startX = emailList[0].key
		else
			startX = commitList[0].key
		if(emailList[emailList.length - 1].key > commitList[commitList.length - 1].key)
			endX = emailList[emailList.length - 1].key
		else
			endX = commitList[commitList.length - 1].key
	} else if(!foundemail) {
		startX = commitList[0].key
		endX = commitList[commitList.length - 1].key
	} else if(!foundcommit) {
		startX = emailList[0].key
		endX = emailList[emailList.length - 1].key
	}
	if(foundissue) {
		if(issueList[0].key < startX)
			startX = issueList[0].key
		if(issueList[issueList.length - 1].key > endX)
			endX = issueList[issueList.length - 1].key
	}

	// create date list and labels
	var labels = createlabels(startX, endX, datatime)

	// get the canvas
	var canvas = document.getElementById("canvas");

	// create datas for the chart
	// data for commits
	var data1 = new Data("bar", "commits", new Color(31, 119, 180, 0.65));
	// reactions on click
	data1.setSelectedFunction(selectedData);
	if(foundcommit) {
		for(var i in commitList) {
			var x = getXPosition(commitList, i, labels, datatime)
			data1.add(x, commitList[i].value, commitList[i].key);
		}
	}
	// data for emails
	var data2 = new Data("bar", "emails", new Color(52, 191, 95, 0.65));
	// reactions on click
	data2.setSelectedFunction(selectedData);
	if(foundemail) {
		for(var i in emailList) {
			var x = getXPosition(emailList, i, labels, datatime)
			data2.add(x, emailList[i].value, emailList[i].key);
		}
	}
	// data for issues
	var data3 = new Data("color", "issues", new Color(255, 0, 0, 0.65));
	// reactions on click
	data3.setSelectedFunction(selectedData);
	if(foundissue) {
		issueList = distributesIssuesForLabels(labels, issueList, datatime);
		for(var i in issueList) {
			data3.add(i, issueList[i].value, issueList[i].key);
		}
	}
	chart = new MirrorChart(canvas, labels, data1, data2, "rgba(0,0,0,0.8)");
	chart.dataMiddle = data3;
	chart.setMaxYUp();
	chart.setMaxYDown();
	chart.setBackground(imgCommits, imgEmails);

	if(labels.length < maximumNumberOfDataToShow)
		chart.drawChart([0, labels.length]);
	else
		chart.drawChart([0, maximumNumberOfDataToShow]);
}

/**
 * Show data to the right of the current visualization of the given chart
 *
 * @param chart
 */
function moveChartToRight(chart) {
	var range = chart.getCurrentRange();
	var start = range[0];
	var end = range[1];
	start += stepSizeOnMoveChart;
	end += stepSizeOnMoveChart;
	if(start > chart.labels.length || end > chart.labels.length) {
		end = chart.labels.length;
		start = end - maximumNumberOfDataToShow;
	}
	chart.clear();
	chart.drawChart([start, end], false);
}


function drawFilterChart(){
	//create commit list
	if(filterCommitList.length != 0) {
		foundcommit = true;
	} else
		foundcommit = false;
	//create email list
	if(filterEmailList.length != 0) {
		foundemail = true;
	} else
		foundemail = false;
	//create issue list
	if(filterIssueList.length != 0) {
		foundissue = true;
	} else
		foundissue = false;

	// get minimum and maximum x values (on non filtered data)
	if(foundcommit && foundemail) {
		if(emailList[0].key < commitList[0].key)
			startX = emailList[0].key
		else
			startX = commitList[0].key
		if(emailList[emailList.length - 1].key > commitList[commitList.length - 1].key)
			endX = emailList[emailList.length - 1].key
		else
			endX = commitList[commitList.length - 1].key
	} else if(!foundemail) {
		startX = commitList[0].key
		endX = commitList[commitList.length - 1].key
	} else if(!foundcommit) {
		startX = emailList[0].key
		endX = emailList[emailList.length - 1].key
	}
	if(foundissue) {
		if(issueList[0].key < startX)
			startX = issueList[0].key
		if(issueList[issueList.length - 1].key > endX)
			endX = issueList[issueList.length - 1].key
	}

	// create date list and labels
	var labels = createlabels(startX, endX, datatime)

	// get the canvas
	var canvas = document.getElementById("filter-canvas");

	// create datas for the chart
	// data for commits
	var data1 = new Data("bar", "commits", new Color(31, 119, 180, 0.65));
	// reactions on click
	data1.setSelectedFunction(selectedData);
	if(foundcommit) {
		for(var i in filterCommitList) {
			var x = getXPosition(filterCommitList, i, labels, datatime)
			data1.add(x, filterCommitList[i].value, filterCommitList[i].key);
		}
	}
	// data for emails
	var data2 = new Data("bar", "emails", new Color(52, 191, 95, 0.65));
	// reactions on click
	data2.setSelectedFunction(selectedData);
	if(foundemail) {
		for(var i in filterEmailList) {
			var x = getXPosition(filterEmailList, i, labels, datatime)
			data2.add(x, filterEmailList[i].value, filterEmailList[i].key);
		}
	}
	// data for issues
	var data3 = new Data("color", "issues", new Color(255, 0, 0, 0.65));
	// reactions on click
	data3.setSelectedFunction(selectedData);
	if(foundissue) {
		filterIssueList = distributesIssuesForLabels(labels, filterIssueList, datatime);
		for(var i in filterIssueList) {
			data3.add(i, filterIssueList[i].value, filterIssueList[i].key);
		}
	}
	filterchart = new MirrorChart(canvas, labels, data1, data2, "rgba(0,0,0,0.8)");
	filterchart.dataMiddle = data3;
	filterchart.setMaxYUp();
	filterchart.setMaxYDown();
	filterchart.setBackground(imgCommits, imgEmails);

	if(labels.length < maximumNumberOfDataToShow)
		filterchart.drawChart([0, labels.length]);
	else
		filterchart.drawChart([0, maximumNumberOfDataToShow]);
}

/**
 * Show data to the left of the current visualization of the given chart
 *
 * @param chart
 */
function moveChartToLeft(chart) {
	var range = chart.getCurrentRange();
	var start = range[0];
	var end = range[1];
	start -= stepSizeOnMoveChart;
	end -= stepSizeOnMoveChart;
	if(start < 0 || end < 0) {
		start = 0;
		end = start + maximumNumberOfDataToShow;
	}
	chart.clear();
	chart.drawChart([start, end], false);
}